/* Copyright 2021 Kerim Yalcin
**
**   Licensed under the Apache License, Version 2.0 (the "License");
**   you may not use this file except in compliance with the License.
**   You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
**   Unless required by applicable law or agreed to in writing, software
**   distributed under the License is distributed on an "AS IS" BASIS,
**   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
**   See the License for the specific language governing permissions and
**   limitations under the License.
*/

#ifndef AGX_WINDOWFRAME_HEADER
#define AGX_WINDOWFRAME_HEADER

#include <vector>
#include <string>
#include <iostream>

#include <windows.h>

#include "WindowBase.hpp"

namespace Agx {

class WindowFrame {
    private:
        WNDCLASSEXA mWndClass;

        std::string mWndClass_Name;
        UINT mWndClass_Style;
        WNDPROC mWndClass_Procedure;
        int mWndClass_ClassExtra;
        int mWndClass_WindowExtra;
        HINSTANCE mWndClass_Instance;
        HICON mWndClass_Icon;
        HICON mWndClass_Icon_small;
        HCURSOR mWndClass_Cursor;
        HBRUSH mWndClass_Background;
        std::string mWndClass_MenuName;

        static LRESULT CALLBACK WindowProcedure_toWNDCLASSEXA(HWND pHwnd, UINT pMsg, WPARAM pWParam, LPARAM pLParam);

        void print_Win32_Error(const std::string& pDescription);

    protected:
        std::vector<WindowFrame*> mWindowFrame_Set;
        std::vector<WindowBase*> mWindowBase_Set;

        void set_WndClass_Name(const std::string& pWndClassName);
        const std::string& get_WndClass_Name();
        void set_WndClass_Instance(HINSTANCE pWndClass_Instance);
        HINSTANCE get_WndClass_Instance();
        void set_WndClass_Background(HBRUSH pWndClass_Background);
        HBRUSH get_WndClass_Background();

        void register_WndClass();

        void add_toWindowBase_Set(WindowBase* pWindowBase);
        void free_WindowBase_Set();

    public:
        WindowFrame();
        virtual LRESULT CALLBACK Window_Procedure(HWND pHwnd, UINT pMsg, WPARAM pWParam, LPARAM pLParam);
        
        virtual LRESULT CALLBACK Window_Procedure_Create(HWND pHwnd, UINT pMsg, WPARAM pWParam, LPARAM pLParam)
            {return DefWindowProcA(pHwnd, pMsg, pWParam, pLParam);};
        virtual LRESULT CALLBACK Window_Procedure_Close(HWND pHwnd, UINT pMsg, WPARAM pWParam, LPARAM pLParam)
            {return DefWindowProcA(pHwnd, pMsg, pWParam, pLParam);};
        virtual LRESULT CALLBACK Window_Procedure_Destroy(HWND pHwnd, UINT pMsg, WPARAM pWParam, LPARAM pLParam)
            {return DefWindowProcA(pHwnd, pMsg, pWParam, pLParam);};
        virtual LRESULT CALLBACK Window_Procedure_Command(HWND pHwnd, UINT pMsg, WPARAM pWParam, LPARAM pLParam)
            {return DefWindowProcA(pHwnd, pMsg, pWParam, pLParam);};
        virtual LRESULT CALLBACK Window_Procedure_Notify(HWND pHwnd, UINT pMsg, WPARAM pWParam, LPARAM pLParam)
            {return DefWindowProcA(pHwnd, pMsg, pWParam, pLParam);};

        virtual int run(HINSTANCE pInstance, HINSTANCE pPreviousInstance, PSTR pCmdLine, INT pCmdShow);
};

}

#endif